package middleware

import (
	"go_stu_gin/config"
	"go_stu_gin/util"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

type JWTClaims struct {
	jwt.StandardClaims
	Id   int    `json:"id"`
	Name string `json:"name"`
}

func Auth() gin.HandlerFunc {
	return func(c *gin.Context) {
		token := c.GetHeader("Authorization")
		if token != "" {
			claims, err := VerifyUserToken(token)
			if err != nil {
				util.ReturnJson(c, util.NOTLOGIN, err, "令牌错误.")
				c.Abort()
				return
			}
			//放入关键参数到context
			c.Set("id", claims.Id)
			c.Set("name", claims.Name)
			c.Next()
		} else {
			c.Writer.WriteHeader(401)
			util.ReturnJson(c, util.NOTLOGIN, nil, "暂未授权")
			c.Abort()
			return
		}
	}
}

//解析令牌
func VerifyUserToken(strToken string) (*JWTClaims, error) {
	JwtSecret := config.MyConfig.JwtAuth.Secret
	token, err := jwt.ParseWithClaims(strToken, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(JwtSecret), nil
	})
	if err != nil {
		return nil, err
	}
	claims, ok := token.Claims.(*JWTClaims)
	if !ok {
		return nil, err
	}
	if err = token.Claims.Valid(); err != nil {
		return nil, err
	}
	return claims, nil
}

// 生成密钥
func CreateToken(claims *JWTClaims) (string, error) {
	JwtSecret := config.MyConfig.JwtAuth.Secret
	JwtExpireTime := config.MyConfig.JwtAuth.ExpireTime
	claims.IssuedAt = time.Now().Unix()
	claims.ExpiresAt = time.Now().Add(time.Second * time.Duration(JwtExpireTime)).Unix()
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	signedToken, err := token.SignedString([]byte(JwtSecret))
	if err != nil {
		return "", err
	}
	return signedToken, nil
}
